%==========================================================================
%=  This file is part of the Sound Restoration Project
%=  (c) Copyright Industrial Mathematics Institute
%=                University of South Carolina, Department of Mathematics
%=  ALL RIGHTS RESERVED
%=
%=  Author: Borislav Karaivanov
%==========================================================================

%==========================================================================
% List of the files on which this procedure depends:
%
% none
%
%==========================================================================

%==========================================================================
% The function "tidyLogFile" removes duplicate lines and groups the
% remaining lines in a given log text file.
% INPUT: "logFileName" is a string the name of the log text file to be
% processed.
% OUTPUT: None.
%==========================================================================
function tidyLogFile(logFileName)
% tidyLogFile('C:\E\NEHScans\NEH144\Results001\log.txt');

% Verify that the log file exists.
if (exist(logFileName, 'file') ~= 2)
    warning('SoundRestoration:tidyLogFile:LogFileInexisting', ...
        '(in tidyLogFile) the log file %s can not be found.\n', logFileName);
    return;
end

% Open the log file for reading.
fid = fopen(logFileName, 'r');
if (fid == -1)
    warning('SoundRestoration:tidyLogFile:CanNotReadLogFile', ...
        '(in tidyLogFile) unable to open the file %s for reading.\n', logFileName);
    return;
end

% Count the lines in the log file.
currLine = fgetl(fid);
numLines = 0;
while ischar(currLine)
    numLines = numLines + 1;
    currLine = fgetl(fid);
end

% Close the log file.
fclose(fid);


% Allocate a cell array to store the lines read from the log file.
lineCellArr = cell(numLines, 1);

% Open the log file for reading once again.
fid = fopen(logFileName, 'r');

% Read each line and store it into a single cell of a cell array.
currLine = fgetl(fid);
lineInd = 0;
while ischar(currLine)
    lineInd = lineInd + 1;
    lineCellArr{lineInd} = currLine;
    currLine = fgetl(fid);
end

% Close the file.
fclose(fid);

% Find any lines representing comments (i.e., starting with % sign).
funHandle = @(x) ((~isempty(x))&&(x(1) == '%'));
isCommentArr = cellfun(funHandle, lineCellArr);

% Remove any duplicate lines among those that are not comments.
nonCommentIndArr = find(~isCommentArr);
[~, origIndArr] = unique(lineCellArr(nonCommentIndArr), 'first');
% Combine indices of the comment lines and the unique non-comment lines.
keepIndArr = [find(isCommentArr); nonCommentIndArr(origIndArr)];
% Sort the combined array in order to preserve the original order of the
% kept lines.
lineCellArr = lineCellArr(sort(keepIndArr, 'ascend'));


% Find all lines holding a timing and store them in a separate cell array.
timingStr = 'Timing: ';
indArr = cellfun((@(x) strcmp(x(1:min(numel(timingStr), end)), timingStr)), lineCellArr);
timingCellArr = lineCellArr(indArr);
% Remove the found lines from the cell array of all lines.
lineCellArr = lineCellArr(~indArr);


% Allocate memory for all timings.
numTimings = numel(timingCellArr);
timingArr = zeros(numTimings, 1);

% Find all timings.
for k = 1:numel(timingCellArr)
    strCellOfCellArr = textscan(timingCellArr{k}, '%s');
    timingArr(k) = str2double(strCellOfCellArr{1}{end - 1});
end 
% Sum up all timings to get the total time.
totalTime = sum(timingArr);

% Append to each line its timing as percentage of the total time without
% the time used for searching fro soundtrack boundaries.
for k = 1:numTimings
    timingCellArr{k} = [timingCellArr{k} ' (' num2str(timingArr(k)*100/totalTime, '%.2f') '%)'];
end

% Add one more cell to the array of timings.
timingCellArr = [timingCellArr; cell(1, 1)];
timingCellArr{end} = ['Timing: total time is ' num2str(totalTime) ' seconds (100.00%)'];

% Find all lines holding the number of scans and store them in a separate
% cell array.
numScansStr = 'number of scans: ';
indArr = cellfun((@(x) strcmp(x(1:min(numel(numScansStr), end)), numScansStr)), lineCellArr);
numScans = sscanf(lineCellArr{indArr(1)}, [numScansStr '%d\n']);
secPerFrame = totalTime/numScans;

% Add one more cell to the array of timings.
timingCellArr = [cell(1, 1); timingCellArr];
timingCellArr{1} = ['Timing: ' num2str(secPerFrame, '%.1f') ' seconds per frame (approximately ' ...
    num2str(60/secPerFrame, '%.0f') ' frames per minute)'];


% Find all lines holding a warning and store them in a separate cell array.
warningStr = 'Warning: (in ';
indArr = cellfun((@(x) strcmp(x(1:min(numel(warningStr), end)), warningStr)), lineCellArr);
warningCellArr = lineCellArr(indArr);
% Remove the found lines from the cell array of all lines.
lineCellArr = lineCellArr(~indArr);


% Open the log file for writing.
fid = fopen(logFileName, 'wt');
if (fid == -1)
    warning('SoundRestoration:tidyLogFile:CanNotWriteToLogFile', ...
        '(in tidyLogFile) unable to open the file %s for writing.\n', logFileName);
    return;
end

% Get relevant system information for the machine currently executing the
% program.
systemInfoLineCellArr = getRelevantSystemInfo({'OS', 'System Model', ...
     'System Type', 'Processor', 'BIOS', 'Memory'});

 
% Write out all timings.
fprintf(fid, '%s\n', timingCellArr{:});
fprintf(fid, ' \n');
% Write out all warnings.
fprintf(fid, '%s\n', warningCellArr{:});
% Write out all line except those holding a timing or a warning.
fprintf(fid, '%s\n', lineCellArr{:});
fprintf(fid, ' \n');
% Write out the relevant system information.
fprintf(fid, ' \n');
fprintf(fid, 'System Info\n');
fprintf(fid, '%s\n', systemInfoLineCellArr{:});
fprintf(fid, ' \n');
% Write out the contact information.
fprintf(fid, ' \n');
fprintf(fid, 'Thank you for using AEO-Light! Your feedback is always welcome and greatly appreciated.\n');
fprintf(fid, 'For bugs, comments, and suggestion, please, contact Borislav Karaivanov at karaivan@math.sc.edu. \n');
fprintf(fid, '\n');

% Close the log file.
fclose(fid);

return;
% end of the function "tidyLogFile"
